/**************************************************************************************
*
*	Copyright (C) 2009 - 2012 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	RasterizerStage.cpp
*
*	Comments	-	See RenderEntrySwapChain.h
*
**************************************************************************************/
#include "../Include/RasterizerStage.h"
#include "../Include/Renderer.h"
#include "../Include/RasterizerState.h"
#include "../Include/Viewport.h"

namespace Pulse
{
	void RasterizerStageState::Clear( void )
	{
		m_pState = PSX_NULL;
		//m_pViewport = PSX_NULL;
		PSX_ZeroMem( &m_viewport, sizeof(m_viewport) );
		//m_rect.Set( 0, 0, 0, 0 );
		PSX_ZeroMem( &m_scissorRect, sizeof(m_scissorRect) );
	}

	RasterizerStage::RasterizerStage( void )
	{
		m_currentState.Clear();
		m_desiredState.Clear();

		m_bUpdateRasterState = TRUE;
		m_bUpdateViewport = TRUE;
		m_bUpdateScissorRect = TRUE;
	}

	RasterizerStage::~RasterizerStage( void )
	{
	}

	void RasterizerStage::SetRasterizerState( RasterizerState *pState )
	{
		// NOTE: Should we have these if checks for performance?
		if ( m_desiredState.m_pState != pState )
		{
			m_desiredState.m_pState = pState;
			m_bUpdateRasterState = TRUE;
		}
	}

	void RasterizerStage::SetScissorRect( Rect *pRect  )
	{
		m_desiredState.m_scissorRect = *pRect;
		m_bUpdateScissorRect = TRUE;
	}

	void RasterizerStage::SetViewport( Viewport *pViewport )
	{
		m_desiredState.m_viewport = *pViewport;
		m_bUpdateViewport = TRUE;
	}

	void RasterizerStage::ClearStates( void )
	{
		//m_currentState.Clear();
		m_desiredState.Clear();
	}

	void RasterizerStage::BindRasterizerState( void )
	{
		if ( m_bUpdateRasterState )
		{
			ID3D11DeviceContext *pDC = (ID3D11DeviceContext*)m_pRenderer->GetNakedDeviceContext();
			pDC->RSSetState( (ID3D11RasterizerState*)m_desiredState.m_pState->GetNakedRasterizerState() );
			m_bUpdateRasterState = FALSE;
		}
	}

	void RasterizerStage::BindScissorRect( void )
	{
		if ( m_bUpdateScissorRect )
		{
			D3D11_RECT;
			ID3D11DeviceContext *pDC = (ID3D11DeviceContext*)m_pRenderer->GetNakedDeviceContext();
			D3D11_RECT rect = { m_desiredState.m_scissorRect.left, m_desiredState.m_scissorRect.top,
				m_desiredState.m_scissorRect.right, m_desiredState.m_scissorRect.bottom };

			pDC->RSSetScissorRects( 1, &rect );

			m_currentState.m_scissorRect = m_desiredState.m_scissorRect;
			m_bUpdateScissorRect = FALSE;
		}
	}

	void RasterizerStage::BindViewport( void )
	{
		if ( m_bUpdateViewport )
		{
			D3D11_VIEWPORT viewport = { m_desiredState.m_viewport.topLeftX, m_desiredState.m_viewport.topLeftY,
				m_desiredState.m_viewport.width, m_desiredState.m_viewport.height, m_desiredState.m_viewport.minDepth,
				m_desiredState.m_viewport.maxDepth };

			ID3D11DeviceContext *pDC = (ID3D11DeviceContext*)m_pRenderer->GetNakedDeviceContext();
			pDC->RSSetViewports( 1, &viewport );

			m_currentState.m_viewport = m_desiredState.m_viewport;
			m_bUpdateViewport = FALSE;
		}
	}

}